﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;

using System.IO;
namespace JGICSoft.Tools
{
    namespace StripperLib
    {
        /// <summary>
        /// Stripper Remove Diacritics and other unwanted caracter to fabric a more standardized file naming.
        /// </summary>
        /// TODO clean public static class Stripper
        public static class Stripper
        {

            public static string RemoveEverythingBad(string stIn)
            {
                string c = Stripper.RemoveDiacritics(stIn);
                c = Stripper.RemoveDiacritics(c);
                c = Stripper.RemoveSpace(c);
                c = Stripper.RemoveQuote(c);
                c = Stripper.RemoveCaracter(c, '[', '_');
                c = Stripper.RemoveCaracter(c, ']', '_');
                c = Stripper.RemoveCaracter(c, '(', '_');
                c = Stripper.RemoveCaracter(c, ')', '_');
                c = Stripper.RemoveCaracter(c, '{', '_');
                c = Stripper.RemoveCaracter(c, '}', '_');
                return c;
            }

            /// <summary>
            /// RemoveCaracter
            /// </summary>
            /// <example>
            /// RemoveCaracter("test d'abc[",'[','_');
            /// </example>
            /// <param name="stIn"></param>
            /// <param name="oldChar"></param>
            /// <param name="newChar"></param>
            /// <returns></returns>
            public static string RemoveCaracter(string stIn, char oldChar, char newChar)
            {
                StringBuilder sb = new StringBuilder();
                for (int ich = 0; ich < stIn.Length; ich++)
                {
                    if (stIn[ich] != oldChar)
                    {
                        sb.Append(stIn[ich]);
                    }
                    else
                    {
                        sb.Append(newChar);
                    }
                }

                return (sb.ToString().Normalize(NormalizationForm.FormC));

            }


            public static string RemoveDiacritics(string stIn)
            {
                string stFormD = stIn.Normalize(NormalizationForm.FormD);
                StringBuilder sb = new StringBuilder();

                for (int ich = 0; ich < stFormD.Length; ich++)
                {
                    UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
                    if (uc != UnicodeCategory.NonSpacingMark)
                    {
                        sb.Append(stFormD[ich]);
                    }
                }

                return (sb.ToString().Normalize(NormalizationForm.FormC));
            }


            public static string RemoveSpace(string stIn)
            {
                StringBuilder sb = new StringBuilder();
                for (int ich = 0; ich < stIn.Length; ich++)
                {
                    if (stIn[ich] != ' ')
                    {
                        sb.Append(stIn[ich]);
                    }
                    else
                    {
                        sb.Append('_');
                    }
                }

                return (sb.ToString().Normalize(NormalizationForm.FormC));
            }

            public static string RemoveQuote(string stIn)
            {
                StringBuilder sb = new StringBuilder();
                for (int ich = 0; ich < stIn.Length; ich++)
                {
                    if (stIn[ich] != '\'')
                    {
                        sb.Append(stIn[ich]);
                    }
                    else
                    {
                        sb.Append('_');
                    }
                }

                return (sb.ToString().Normalize(NormalizationForm.FormC));
            }


            /// <summary>
            /// That should rename after stripping
            /// </summary>
            /// <remarks>untested</remarks>
            /// <param name="sbsrc">source file (complete path or filename (must have execute the app in the current folder where file is</param>
            /// <returns>done it or not</returns>
            public static StripperSvc.ASMX.ServiceContracts.StripAndRenameResponse RenameAndStripAFileName(StripperSvc.ASMX.ServiceContracts.StripAndRenameRequest request)
            {
                bool DEBUG = request.DEBUGMODE;
                StringBuilder sb = new StringBuilder(1024);
                using (StringWriter sr = new StringWriter(sb))
                {
                    sr.WriteLine("===========================================");

                    StripperSvc.ASMX.DataTypes.StripAndRenameResult result = new StripperSvc.ASMX.DataTypes.StripAndRenameResult();
                    StripperSvc.ASMX.DataTypes.MetaData metadata = new StripperSvc.ASMX.DataTypes.MetaData();
                    StripperSvc.ASMX.ServiceContracts.StripAndRenameResponse response = new StripperSvc.ASMX.ServiceContracts.StripAndRenameResponse();
                    StripperSvc.ASMX.DataTypes.StripAndRenameFault fault = new StripperSvc.ASMX.DataTypes.StripAndRenameFault();
                    string InputOri = request.FullFilePath;
                    string fullpath = System.IO.Path.GetFullPath(request.FullFilePath);
                    string FileNamedest = "";
                    string FileName = "";
                    string PathRoot = "";
                    string fullpathdest = "";
                    try
                    {
                        sr.Write("Getting fullpath: " + fullpath);
                        FileName = System.IO.Path.GetFileName(fullpath);
                        if (DEBUG) sr.WriteLine("FileName = " + FileName);

                    }
                    catch (Exception ex)
                    {
                        FileName = request.FullFilePath; //looks useless (in case only a name is supplied)
                        //TODO is something about current dir relevant?
                        sr.WriteLine(ex.Message);
                      if (DEBUG)  sr.WriteLine("FileName = sbsrc;");
                    }

                    try
                    {
                        PathRoot = System.IO.Path.GetDirectoryName(fullpath);
                    }
                    catch (Exception ex)
                    {
                        PathRoot = Environment.CurrentDirectory;
                        sr.WriteLine("USED: PathRoot = Environment.CurrentDirectory");
                    }

                    FileNamedest = RemoveEverythingBad(FileName);
                    fullpathdest = Path.Combine(PathRoot, FileNamedest);

                    metadata.InputOriginalData = InputOri;
                    metadata.OriginalPathRoot = PathRoot;
                    metadata.OriginalPath = fullpath;
                    metadata.StrippedPath = fullpathdest;
                    metadata.OriginalFileName = FileName;
                    metadata.NewFileName = FileNamedest;

                    try
                    {
                        if (File.Exists(fullpath))
                        {

                            sr.WriteLine("File.Move(" + fullpath + "," + fullpathdest + ");");
                            File.Move(fullpath, fullpathdest);
                            result.Succeeded = true;
                            //response.ResponseMessage = sr.ToString();
                            //response.ResponseResultData = result;
                            //return response;
                        }
                        else
                        {
                            sr.WriteLine("else (File.Exists(fullpath))");
                            result.Succeeded = false;
                           // response.ResponseMessage = sr.ToString();
                            //response.ResponseResultData = result;
                            //return response;
                        }

                        // Console.WriteLine("done.");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        result.Succeeded = false;
                        //response.ResponseMessage = sr.ToString();
                        //response.ResponseResultData = result;
                        //return response;
                        // Console.WriteLine(ex.Message);
                        //Console.WriteLine("did not work...\nsorry");
                    }

                    
                    //result.Succeeded = true;
                    result.MetaData = metadata;
                    response.ResponseMessage = sr.ToString();
                    response.ResponseResultData = result;
                    
                    return response;
                }

            }

        }
    }
}